<template>
    <div class="node-create">
        <div class="custom-header">
            <div class="header-inner">
                <div class="header-row">
                    <div class="header-left" @click="goBack">
                        <svg class="back-icon" viewBox="0 0 16 16" aria-hidden="true">
                            <path d="M10.5 13 6 8l4.5-5" stroke="currentColor" stroke-width="1.5" fill="none"
                                stroke-linecap="round" stroke-linejoin="round" />
                        </svg>
                        <span class="back-text">返回</span>
                    </div>
                    <span class="header-divider" aria-hidden="true"></span>
                    <span class="header-title">详情</span>
                </div>
            </div>
        </div>

        <!-- 内容区域 -->
        <div class="content-outer">
            <div class="content-wrap">
                <div class="content-inner">
                    <!-- 基础信息 -->
                    <div class="section-info">
                        <div class="info-row">
                            <span class="info-label">索引名称：</span>
                            <span class="info-value">{{ formData.indexName || '—' }}</span>
                        </div>

                        <div class="info-row info-row--type">
                            <a-form layout="inline" class="info-form">
                                <a-form-item label="索引类型" class="inline-item">
                                    <a-select v-model:value="formData.indexType" disabled placeholder="—">
                                        <a-select-option :value="formData.indexType" v-if="formData.indexType">
                                            {{ formData.indexType }}
                                        </a-select-option>
                                    </a-select>
                                </a-form-item>
                            </a-form>
                        </div>

                        <div class="info-row info-row--type">
                            <a-form layout="inline" class="info-form">
                                <a-form-item label="索引权限" class="inline-item">
                                    <a-select v-model:value="formData.indexPermission" disabled placeholder="—">
                                        <a-select-option :value="formData.indexPermission"
                                            v-if="formData.indexPermission">
                                            {{ formData.indexPermission }}
                                        </a-select-option>
                                    </a-select>
                                </a-form-item>
                            </a-form>
                        </div>

                        <div class="info-row">
                            <span class="info-label">发布时间：</span>
                            <span class="info-value">{{ formData.publishTime || '—' }}</span>
                        </div>

                        <div class="info-row">
                            <span class="info-label">更新状态：</span>
                            <span class="info-value">{{ getStatusDisplay() }}</span>
                        </div>

                        <div class="info-row">
                            <span class="info-label">文档数量：</span>
                            <span class="info-value">{{ formatNumber(formData.docCount) }}</span>
                        </div>

                        <div class="info-row">
                            <span class="info-label">更新时间：</span>
                            <span class="info-value">{{ formData.updateTime || '—' }}</span>
                        </div>

                        <div class="info-row">
                            <span class="info-label">创建人：</span>
                            <span class="info-value">{{ formData.creator || '—' }}</span>
                        </div>

                        <div class="info-row">
                            <span class="info-label">备注：</span>
                            <span class="info-value">{{ formData.remark || '—' }}</span>
                        </div>
                    </div>

                    <!-- 生产源列表 -->
                    <section class="section section-prod">
                        <div class="section-title">生产源列表</div>
                        <a-table :data-source="dataSource" :loading="prodLoading || detailLoading"
                            :columns="dataSourceColumns" row-key="id" class="custom-table mt-10" :pagination="false"
                            bordered />
                    </section>

                    <!-- 数据同步策略 -->
                    <section class="section section-sync">
                        <a-form layout="vertical" class="sync-form">
                            <a-form-item label="数据同步策略：">
                                <a-select v-model:value="formData.syncStrategy" disabled class="w-400" placeholder="—">
                                    <a-select-option :value="formData.syncStrategy" v-if="formData.syncStrategy">
                                        {{ formData.syncStrategy }}
                                    </a-select-option>
                                </a-select>
                            </a-form-item>
                        </a-form>
                    </section>

                    <!-- 数据同步参数 -->
                    <section class="section section-sync-params">
                        <a-form layout="vertical" class="sync-form">
                            <a-form-item label="数据同步参数：">
                                <a-input v-model:value="formData.syncExpression" disabled class="w-400"
                                    placeholder="—" />
                            </a-form-item>
                        </a-form>
                    </section>

                    <!-- 倒排索引Mapping配置 -->
                    <section class="section section-mapping">
                        <div class="section-title">倒排索引Mapping配置</div>

                        <a-table :data-source="mappingData" :columns="mappingColumnsReadonly" row-key="id"
                            class="mapping-table mt-10" :pagination="false" bordered>
                            <template #bodyCell="{ text, record, column }">
                                <template v-if="['isIndexed', 'isStored'].includes(column.key)">
                                    <span :class="{
                                        'bool-true': record[column.key] === '是',
                                        'bool-false': record[column.key] === '否'
                                    }">{{ record[column.key] ?? '—' }}</span>
                                </template>
                                <span v-else>{{ text ?? '—' }}</span>
                            </template>
                        </a-table>

                        <!-- 向量索引Mapping配置 -->
                        <div class="section-title mt-16">向量索引Mapping配置</div>
                        <a-table :data-source="vectorMappingData" :columns="vectorColumnsReadonly" row-key="_rid"
                            class="mapping-table vector-table mt-10" :pagination="false" bordered>
                            <template #bodyCell="{ text, record, column }">
                                <template v-if="column.key === 'isIndexed'">
                                    <span :class="{
                                        'bool-true': record.isIndexed === '是',
                                        'bool-false': record.isIndexed === '否'
                                    }">{{ record.isIndexed ?? '—' }}</span>
                                </template>
                                <span v-else>{{ text ?? '—' }}</span>
                            </template>
                        </a-table>

                        <!-- ===== 底部按钮 ===== -->
                        <div class="actions-bar mt-16">
                            <a-button class="btn-cancel" @click="goBack">返 回</a-button>
                            <a-button type="primary" class="btn-save" :disabled="true">保 存</a-button>
                        </div>
                    </section>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import Http from "@/api";
import { message } from "ant-design-vue";

/* ===== 路由 ===== */
const router = useRouter();
const route = useRoute();
const goBack = () => router.back();

/* ===== 基础信息 ===== */
const formData = reactive({
    indexName: "",
    indexType: "",
    indexPermission: "",
    publishTime: "",
    updateTime: "",
    creator: "",
    remark: "",
    syncStrategy: "",
    syncExpression: "",
    updateStatus: "",
    syncProgress: "",
    docCount: 0,
    indexUpdateStrategy: "",
    indexUpdateTimeStrategy: "",
});

const indexId = ref<string>("");
const sourceId = ref<string>("");

/* 工具 */
const formatYMDHMS = (input: any) => {
    if (!input) return "";
    const d = new Date(input);
    if (isNaN(d.getTime())) return String(input);
    const pad = (n: number) => (n < 10 ? `0${n}` : `${n}`);
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(
        d.getMinutes()
    )}:${pad(d.getSeconds())}`;
};
const formatNumber = (n: any) => {
    const x = Number(n);
    return Number.isFinite(x) ? x.toLocaleString() : "—";
};
const ynToBoolStr = (v: any) =>
    v === "Y" || v === "y" || v === true || v === "true" ? "是"
        : v === "N" || v === "n" || v === false || v === "false" ? "否"
            : String(v ?? "");

const getStatusDisplay = () => {
    const raw = String(formData.updateStatus || "").trim();
    const p = String(formData.syncProgress || "").trim();
    const pct = p.replace(/[^\d.]/g, "");
    const progressPart = pct ? ` ${Math.min(100, Math.max(0, Number(pct)))}%` : "";
    if (!raw && !progressPart) return "—";
    const map: Record<string, string> = {
        running: "进行中",
        processing: "进行中",
        进行中: "进行中",
        syncing: "进行中",
        done: "已完成",
        finished: "已完成",
        success: "已完成",
        已完成: "已完成",
        failed: "失败",
        error: "失败",
        失败: "失败",
    };
    const key = raw.toLowerCase();
    const base = map[raw] || map[key] || raw;
    return `${base}${progressPart}`.trim();
};

/* 从路由查询做初始回显 */
const initFromQuery = () => {
    const q = route.query as Record<string, any>;
    indexId.value = String(q.index_id ?? "");
    formData.indexName = q.index_name ?? formData.indexName;
    formData.indexType = q.index_type ?? formData.indexType;
    formData.indexPermission = q.index_permission ?? q.index_perm ?? formData.indexPermission;
    formData.publishTime = q.create_time ? formatYMDHMS(q.create_time) : formData.publishTime || "—";
    formData.updateTime = q.update_time ? formatYMDHMS(q.update_time) : formData.updateTime || "—";
    formData.creator = q.index_owner_id || q.index_owner || formData.creator || "—";
    formData.remark = q.memo ?? formData.remark;
    formData.syncStrategy = q.datasync_strategy ?? formData.syncStrategy;
    formData.updateStatus = q.datasync_message ?? q.update_status ?? q.sync_status ?? q.index_state_text ?? formData.updateStatus;
    formData.syncProgress = q.progress ?? q.sync_progress ?? q.progress_percent ?? formData.syncProgress;
    formData.docCount = Number(q.doc_count ?? formData.docCount) || formData.docCount;
    formData.indexUpdateStrategy = q.index_update_strategy ?? formData.indexUpdateStrategy;
    formData.indexUpdateTimeStrategy = q.index_update_time_strategy ?? formData.indexUpdateTimeStrategy;
};

/* ===== 生产源列表 ===== */
const dataSource = reactive<any[]>([]);
const prodLoading = ref(false);
const dataSourceColumns = [
    { title: "ID", dataIndex: "id", key: "id", align: "center" },
    { title: "生产源名称", dataIndex: "name", key: "name", align: "center" },
    { title: "数据类型", dataIndex: "dataModel", key: "dataModel", align: "center" },
    { title: "数据量", dataIndex: "count", key: "count", align: "center" },
    { title: "更新时间", dataIndex: "updateTime", key: "updateTime", align: "center" },
    { title: "同步状态", dataIndex: "status", key: "status", align: "center" },
];
const patchProdSource = (list: any[]) => {
    if (!Array.isArray(list)) return;
    const rows = list.map((it: any, idx: number) => {
        const id = it.id ?? it.source_id ?? it.prod_id ?? idx + 1;
        const name = it.prod_source_name ?? it.name ?? it.source_name ?? it.prod_name ?? "—";
        const dataModel = it.data_model ?? it.datamodel ?? it.dataModel ?? "—";
        const count = Number(it.data_count ?? it.count ?? it.size ?? it.total ?? it.total_count ?? 0);
        const updateTimeRaw = it.update_time ?? it.updated_at ?? it.updateTime ?? it.last_update_time;
        const updateTime = updateTimeRaw ? formatYMDHMS(updateTimeRaw) : "—";
        const status = String(it.status ?? it.sync_status ?? "—");
        return { id, name, dataModel, count, updateTime, status };
    });
    dataSource.splice(0, dataSource.length, ...rows);
};
const fetchProdSource = async (sid: string) => {
    const sidStr = String(sid ?? "").trim();
    if (!sidStr) {
        dataSource.splice(0, dataSource.length);
        return;
    }
    prodLoading.value = true;
    try {
        const res: any = await Http.getProdSourceInfo({ sourceId: sidStr });
        const payload = res?.data?.data ?? res?.data ?? res;
        const list = Array.isArray(payload)
            ? payload
            : payload && typeof payload === "object"
                ? [payload]
                : [{ id: sidStr, prod_source_name: "", data_model: "", data_count: 0, update_time: null, status: "" }];
        patchProdSource(list);
    } finally {
        prodLoading.value = false;
    }
};

/* ===== Mapping（倒排/向量） ===== */
const mappingData = reactive<any[]>([]);
const mappingColumnsReadonly = [
    { title: "生产源字段名称", dataIndex: "fieldName", key: "fieldName", align: "center" },
    { title: "数据类型", dataIndex: "dataType", key: "dataType", align: "center" },
    { title: "是否索引", dataIndex: "isIndexed", key: "isIndexed", align: "center" },
    { title: "索引字段名称", dataIndex: "indexFieldName", key: "indexFieldName", align: "center" },
    { title: "索引字段类型", dataIndex: "indexType", key: "indexType", align: "center" },
    { title: "是否存储", dataIndex: "isStored", key: "isStored", align: "center" },
    { title: "分词器", dataIndex: "tokenizer", key: "tokenizer", align: "center" },
    { title: "分词词典", dataIndex: "defaultDict", key: "defaultDict", align: "center" },
    { title: "同义词词典", dataIndex: "synonymDict", key: "synonymDict", align: "center" },
    { title: "内容转换规则", dataIndex: "contentRule", key: "contentRule", align: "center" },
    { title: "权重", dataIndex: "weight", key: "weight", align: "center" },
    { title: "备注", dataIndex: "remark", key: "remark", align: "center" },
];
const patchMapping = (list: any[]) => {
    if (!Array.isArray(list)) return;
    const rows = list.map((it: any, idx: number) => {
        const id = it.id ?? it.index_field_no ?? idx + 1;
        const fieldName = it.source_field_name ?? `field_${idx + 1}`;
        const indexFieldName = it.index_field_name ?? "";
        const dataType = (it.source_field_type ?? "").toString().toUpperCase();
        const indexType = (it.index_field_type ?? "").toString().toUpperCase();
        const contentRule = it.field_if_mapping ?? it.content_rule ?? "请选择";
        const rawWeight = it.index_weight ?? it.weight;
        const weight = Number.isFinite(+rawWeight) ? +rawWeight : 0;
        const remark = it.memo ?? "";
        return {
            id,
            fieldName,
            indexFieldName,
            dataType,
            indexType,
            isIndexed: ynToBoolStr(it.if_index),
            isStored: ynToBoolStr(it.if_store),
            tokenizer: it.tokenizer ?? "",
            defaultDict: it.tokenizer_dict_id ?? "",
            synonymDict: it.synonym_dict_id ?? "",
            contentRule,
            weight,
            remark,
        };
    });
    mappingData.splice(0, mappingData.length, ...rows);
};

const vectorMappingData = reactive<any[]>([]);
const vectorColumnsReadonly = [
    { title: "生产源字段名称", dataIndex: "sourceFieldName", key: "sourceFieldName", align: "center" },
    { title: "数据类型", dataIndex: "sourceFieldType", key: "sourceFieldType", align: "center" },
    { title: "是否索引", dataIndex: "isIndexed", key: "isIndexed", align: "center" },
    { title: "索引字段名称", dataIndex: "indexFieldName", key: "indexFieldName", align: "center" },
    { title: "索引类型", dataIndex: "indexFieldType", key: "indexFieldType", align: "center" },
    { title: "向量维度", dataIndex: "vectorDimension", key: "vectorDimension", align: "center" },
    { title: "向量化算法", dataIndex: "vectorAlgorithm", key: "vectorAlgorithm", align: "center" },
    { title: "权重", dataIndex: "weight", key: "weight", align: "center" },
    { title: "备注", dataIndex: "remark", key: "remark", align: "center" },
];
const patchVectorMapping = (list: any[]) => {
    if (!Array.isArray(list)) return;
    const rows = list.map((it: any, idx: number) => ({
        _rid: `${it.index_field_no ?? 'rid'}-${idx}`,
        id: it.index_field_no ?? idx + 1,
        indexId: it.index_id ?? "",
        sourceFieldName: it.source_field_name ?? "",
        sourceFieldType: (it.source_field_type ?? "").toString(),
        isIndexed: ynToBoolStr(it.if_index),
        indexFieldName: it.index_field_name ?? "",
        indexFieldType: (it.index_field_type ?? "").toString(),
        vectorDimension: Number(it.vector_dimension ?? 0),
        vectorAlgorithm: it.vector_algorithm ?? "",
        weight: Number(it.weight ?? it.index_weight ?? 0),
        remark: it.memo ?? "",
    }));
    vectorMappingData.splice(0, vectorMappingData.length, ...rows);
};

/* ===== 详情接口拉取 ===== */
const detailLoading = ref(false);
const fetchDetail = async () => {
    if (!indexId.value) return;
    detailLoading.value = true;
    try {
        const res: any = await Http.getIndexById({ indexId: indexId.value });
        const data = (res?.data?.data ?? res?.data ?? res) as any;

        // 基础信息
        const info = data?.index_info ?? {};
        formData.indexName = info.index_name ?? formData.indexName;
        formData.indexType = info.index_type ?? formData.indexType;
        formData.indexPermission = info.index_permission ?? info.index_perm ?? formData.indexPermission;
        formData.publishTime = info.create_time ? formatYMDHMS(info.create_time) : formData.publishTime || "—";
        formData.updateTime = info.update_time ? formatYMDHMS(info.update_time) : formData.updateTime || "—";
        formData.creator = info.index_owner_id || info.index_owner || formData.creator || "—";
        formData.remark = info.memo ?? formData.remark;
        formData.syncStrategy = info.datasync_strategy ?? formData.syncStrategy;
        formData.updateStatus = info.datasync_message ?? info.update_status ?? info.sync_status ?? info.index_state_text ?? formData.updateStatus;
        formData.syncProgress = info.progress ?? info.sync_progress ?? info.progress_percent ?? formData.syncProgress;
        formData.docCount = Number(info.doc_count ?? formData.docCount) || formData.docCount;
        formData.indexUpdateStrategy = info.index_update_strategy ?? formData.indexUpdateStrategy;
        formData.indexUpdateTimeStrategy = info.index_update_time_strategy ?? formData.indexUpdateTimeStrategy;

        sourceId.value = String(info.source_id ?? "");
        if (sourceId.value) fetchProdSource(sourceId.value);

        // 映射
        patchMapping(data?.mapping_list || data?.index_mapping_items || []);
        patchVectorMapping(data?.vector_mapping_list || []);
    } catch (e) {
        message.error("加载详情失败");
    } finally {
        detailLoading.value = false;
    }
};

onMounted(async () => {
    initFromQuery();
    await fetchDetail();
});
</script>

<style scoped lang="less">
@border-light: #f0f0f0;
@page-bg: #f0f2f5;
@text-strong: #262626;
@text-secondary: #595959;
@font-base: "PingFang SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", "Microsoft YaHei", sans-serif;
@brand-blue: #000;
@section-gap: 24px;
@table-row-h: 40px;
@thead-bg-main: #f4f8fd;

@bool-true-color: #52c41a;
@bool-false-color: #1f1f1f;

:root {
    --text-secondary-858b9b: #858b9b;
    --text-strong-2a2f3c: #2a2f3c;
    --label-color-858b9b: var(--text-secondary-858b9b);
    --value-color-2a2f3c: var(--text-strong-2a2f3c);
}

.font-regular() {
    font-family: @font-base;
    font-weight: 400;
    font-size: 14px;
    line-height: 20px;
    letter-spacing: 0;
}

.section-title-regular() {
    .font-regular();
}

.ant-vertical-66() {
    margin: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 66px;
}

.ant-typography-regular() {
    color: var(--value-color-2a2f3c, #2a2f3c);
    .font-regular();
}

.table-compact(@theadBg: @thead-bg-main, @rowH: @table-row-h) {
    :deep(.ant-table-thead > tr > th) {
        background: @theadBg !important;
        height: @rowH !important;
        padding-top: (@rowH - 20px) / 2 !important;
        padding-bottom: (@rowH - 20px) / 2 !important;
        line-height: 20px !important;
        text-align: center;
    }

    :deep(.ant-table-tbody > tr > td) {
        height: @rowH !important;
        padding-top: (@rowH - 20px) / 2 !important;
        padding-bottom: (@rowH - 20px) / 2 !important;
        line-height: 20px !important;
        vertical-align: middle;
    }

    :deep(.ant-table-column-sorters) {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 4px;
    }
}

/* 页面容器 */
.node-create {
    --page-padding-x: 10px;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    padding: 0 var(--page-padding-x) 24px;
    background: @page-bg;
}

/* 顶部导航 */
.custom-header {
    flex: 0 0 56px;
    height: 56px;
    background: #fff;
    border-bottom: 1px solid @border-light;
    margin-left: calc(-1 * var(--page-padding-x));
    margin-right: calc(-1 * var(--page-padding-x));
    width: calc(100% + var(--page-padding-x) * 2);
}

.header-inner {
    height: 100%;
    padding: 0 16px;
    display: flex;
    align-items: center;
}

.header-row {
    display: inline-flex;
    align-items: center;
}

.header-left {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    user-select: none;
    color: #8c8c8c;
}

.back-icon {
    width: 12px;
    height: 12px;
    margin-left: 16px;
}

.back-text {
    font-family: @font-base;
    font-weight: 400;
    font-size: 14px;
    line-height: 100%;
    color: @text-secondary;
}

.header-divider {
    width: 1px;
    height: 16px;
    background: #d9d9d9;
    margin-left: 16px;
    display: inline-block;
}

.header-title {
    margin-left: 16px;
    font-family: @font-base;
    font-weight: 500;
    font-size: 16px;
    line-height: 100%;
    color: @text-strong;
}

/* 主体 */
.content-outer {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    margin-top: 10px;
    min-height: 0;
}

.content-wrap {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-height: 0;
    flex: 1 1 auto;
}

.content-inner {
    display: flex;
    flex-direction: column;
    gap: @section-gap;
    padding: 10px 24px 0 24px;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    min-height: 0;
    flex: 1 1 auto;
}

/* 基本信息 */
.section-info {
    display: flex;
    flex-direction: column;
    row-gap: 16px;
    margin-top: 14px;
}

.info-row {
    display: flex;
    align-items: center;
    min-height: 22px;
    line-height: 22px;
}

.info-label {
    margin-right: 10px;
    .font-regular();
    color: var(--label-color-858b9b, #858b9b) !important;
}

.info-value {
    .font-regular();
    line-height: 22px;
    color: var(--value-color-2a2f3c, #2a2f2c) !important;
}

.info-row--type {
    min-height: 40px;
    align-items: center;
}

:deep .ant-select .ant-select-selection-item {
    line-height: 30px !important;
}

.info-form {
    width: 100%;
    display: flex;
    align-items: center;

    :deep(.ant-form-item) {
        margin: 0 !important;
    }

    :deep(.ant-form-item-label > label) {
        .ant-typography-regular();
    }

    :deep(.ant-select .ant-select-selector),
    :deep(.ant-select .ant-select-selection-item),
    :deep(.ant-select .ant-select-selection-placeholder) {
        .ant-typography-regular();
    }
}

.inline-item :deep(.ant-form-item-control) {
    min-width: 420px;
}

.inline-item :deep(.ant-select) {
    width: 420px !important;
}

/* 生产源列表 */
.section-prod {
    .section-title {
        .section-title-regular();
    }

    .custom-table {
        .table-compact(@thead-bg-main, @table-row-h);

        :deep(.ant-table-thead > tr > th) {
            color: #81889c !important;
        }

        :deep(.ant-table-tbody > tr > td:nth-child(2)) {
            color: @brand-blue;
        }
    }
}

/* 同步配置区域 */
.section-sync .sync-form,
.section-sync-params .sync-form {
    width: 100%;
    display: flex;
    align-items: center;
}

.section-sync .sync-form :deep(.ant-form-item),
.section-sync-params .sync-form :deep(.ant-form-item) {
    .ant-vertical-66();
}

.section-sync .sync-form :deep(.ant-form-item-label > label),
.section-sync-params .sync-form :deep(.ant-form-item-label > label) {
    .section-title-regular();
    color: var(--value-color-2a2f3c, #2a2f3c);
}

.section-sync .sync-form :deep(.ant-select .ant-select-selector),
.section-sync .sync-form :deep(.ant-select .ant-select-selection-item),
.section-sync .sync-form :deep(.ant-select .ant-select-selection-placeholder),
.section-sync-params .sync-form :deep(.ant-select .ant-select-selector),
.section-sync-params .sync-form :deep(.ant-select .ant-select-selection-item),
.section-sync-params .sync-form :deep(.ant-select .ant-select-selection-placeholder),
.section-sync .sync-form :deep(.ant-input),
.section-sync-params .sync-form :deep(.ant-input) {
    .ant-typography-regular();
}

/* 通用区块与表格 */
.section {
    display: flex;
    flex-direction: column;
}

.section-title {
    font-size: 16px;
    font-weight: 500;
    color: @text-strong;
}

.custom-table,
.mapping-table {
    overflow: auto;

    :deep(.ant-table) {
        min-width: 720px;
    }

    :deep(.ant-table-thead > tr > th) {
        background-color: #e6f7ff;
        font-weight: 500;
    }

    :deep(.ant-table-column-sorters) {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 0;
    }
}

.mapping-table :deep(.ant-table-cell) {
    text-align: center;
}

/* Mapping 区域 */
.section-mapping {
    .section-title {
        .section-title-regular();
    }

    .mapping-table,
    .mapping-table :deep(.ant-table),
    .mapping-table :deep(.ant-table-thead > tr > th),
    .mapping-table :deep(.ant-table-tbody > tr > td),
    .datatype-trigger,
    .datatype-text {
        .font-regular();
        color: var(--value-color-2a2f3c, #2a2f3c);
    }

    .mapping-table {
        .table-compact(@thead-bg-main, @table-row-h);
    }
}

.section-mapping .vector-table :deep(.ant-table-thead > tr > th) {
    background-color: #f4f8fd !important;
}

.bool-true {
    color: @bool-true-color !important;
}

.bool-false {
    color: @bool-false-color !important;
}

.triangle {
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid #1f1f1f;
    display: inline-block;
    transform: translateY(1px);
}


.actions-bar {
    position: static;
    bottom: auto;
    z-index: 1;
    background: transparent;
    border-top: none;
    box-shadow: none;
    display: flex;
    justify-content: center;
    gap: 16px;
    padding: 0;
    margin: 40px !important;
}

.btn-save,
.btn-cancel {
    min-width: 120px;
    height: 36px;
    border-radius: 999px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.06);
}

/* 工具类 */
.w-400 {
    width: 50% !important;
}

.mt-10 {
    margin-top: 10px;
}

.mt-16 {
    margin-top: 16px;
}

/* 适配 */
@media (max-width: 992px) {
    .w-400 {
        width: 100% !important;
    }

    .inline-item :deep(.ant-form-item-control) {
        min-width: 100%;
    }

    .inline-item :deep(.ant-select) {
        width: 100% !important;
    }
}

@media (max-width: 480px) {
    .header-inner {
        padding: 0 12px;
    }

    .content-inner {
        padding: 10px 12px 0 12px;
    }
}

/* 行高（与编辑页一致） */
.section-prod .custom-table {
    :deep(.ant-table-thead > tr > th) {
        height: 40px !important;
        padding-top: 10px !important;
        padding-bottom: 10px !important;
        line-height: 20px !important;
    }

    :deep(.ant-table-tbody > tr > td) {
        height: 40px !important;
        padding-top: 10px !important;
        padding-bottom: 10px !important;
        line-height: 20px !important;
    }
}

.section-mapping .mapping-table {
    :deep(.ant-table-thead > tr > th) {
        height: 40px !important;
        padding-top: 10px !important;
        padding-bottom: 10px !important;
        line-height: 20px !important;
    }

    :deep(.ant-table-tbody > tr > td) {
        height: 40px !important;
        padding-top: 10px !important;
        padding-bottom: 10px !important;
        line-height: 20px !important;
    }
}
</style>
